import { createAction } from '@reduxjs/toolkit'

// 本文件主要用来管理多个rpc调用请求

export interface Call {
  address: string
  callData: string
}

const ADDRESS_REGEX = /^0x[a-fA-F0-9]{40}$/
const LOWER_HEX_REGEX = /^0x[a-f0-9]*$/

// 将rcp调用系列化：       即将函数调用的参数address, callData拼接成一个字符串
export function toCallKey ( call: Call ): string {
  if (!ADDRESS_REGEX.test(call.address)) {   // 拼接前检查是否以0x开头
    throw new Error(`Invalid address: ${call.address}`)
  }
  if (!LOWER_HEX_REGEX.test(call.callData)) {
    throw new Error(`Invalid hex: ${call.callData}`)
  }
  return `${call.address}-${call.callData}`
}

// 解析系列化后的rpc调用字符串： 
// parseCallKey是toCallKey的反函数
export function parseCallKey(callKey: string): Call {
  const pcs = callKey.split('-')
  if (pcs.length !== 2) {
    throw new Error(`Invalid call key: ${callKey}`)
  }
  return {
    address: pcs[0],
    callData: pcs[1]
  }
}

export interface ListenerOptions {
  // how often this data should be fetched, by default 1
  readonly blocksPerFetch?: number
}

// 信号：添加调用的监听
export const addMulticallListeners = createAction<{ chainId: number; calls: Call[]; options?: ListenerOptions }>(
  'multicall/addMulticallListeners'
)
// 信号：移除调用的监听
export const removeMulticallListeners = createAction<{ chainId: number; calls: Call[]; options?: ListenerOptions }>(
  'multicall/removeMulticallListeners'
)
// 信号：获取调用结果
export const fetchingMulticallResults = createAction<{ chainId: number; calls: Call[]; fetchingBlockNumber: number }>(
  'multicall/fetchingMulticallResults'
)
// 信号：获取结果出错
export const errorFetchingMulticallResults = createAction<{
  chainId: number
  calls: Call[]
  fetchingBlockNumber: number
}>( 'multicall/errorFetchingMulticallResults' )

// 信号：更新调用结果
export const updateMulticallResults = createAction<{
  chainId: number
  blockNumber: number
  results: {
    [callKey: string]: string | null
  }
}>('multicall/updateMulticallResults')
